package ar.edu.unq.tpi.pconc.tpconcurbattle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import ar.edu.unq.tpi.concurbattles.ConcurBattles;
import ar.edu.unq.tpi.pconc.Channel;
import ar.edu.unq.tpi.pconc.tpconcurbattle.utils.Util;

public class Tablero {
	
	private static Tablero instance;
	
	private List<Unidad> unidades;
	private Map<String,Ciudad> ciudades;
	private Map<String,Bando> bandos;
	private boolean sinFinalizar;
	private Bando bandoGanador;
	
	private Tablero(List<Unidad> unidades, Map<String,Ciudad> collection,
			Map<String,Bando> bandos) {
		super();
		this.unidades = unidades;
		this.ciudades = collection;
		this.bandos = bandos;
		this.sinFinalizar = true;
	}
	
	public static Tablero newInstance(List<Unidad> unidades, Map<String,Ciudad> collection,
			Map<String,Bando> bandos) {
		instance = new Tablero(unidades, collection, bandos);
		return instance;
	}
	
	public static Tablero getInstance() {
		return instance;
	}
	
	public Bando getBando(String nombre) {
		return this.bandos.get(nombre);
	}
	
	public Ciudad getCiudad(String nombre) {
		return this.ciudades.get(nombre);
	}

	public boolean sinFinalizarJuego() {
		return this.sinFinalizar;
	}

	public Bando getGanador() {
		return this.bandoGanador;
	}
	
	/** Inicializa a todos los threads de las unidades**/
	private void comenzarJuego() {
		Channel<String> guiSend = new Channel<String>(Util.GUI_RECIEVE);
		for(Unidad unidad : this.getUnidades()) {
			guiSend.send(unidad.getGUIid() + " " + unidad.getUbicacion().getId());
			new Thread(unidad).start();
		}
	}
	
	public void finalizarJuego(Bando bandoGanador) {
		this.sinFinalizar = false;
		this.bandoGanador = bandoGanador;
		System.out.println("El juego ha finalizado");
	}
	
	public List<Unidad> getUnidades() {
		return this.unidades;
	}
	
	private static void limpiar() {
		Tablero tablero = Tablero.getInstance();
		if (tablero != null) {
			for (Ciudad ciudad : tablero.ciudades.values()) {
				for (Unidad unidad : ciudad.getUnidades()) {
					unidad.morir();
				}
			}
		}
//		Tablero.getInstance().instance = null;
	}
	
	public static void main(String[] args) {
		Bando gold = new Bando("gold");
		Bando silver = new Bando("silver");
		
		Map<String,Bando> bandos = new HashMap<String, Bando>();
		bandos.put("gold", gold);
		bandos.put("silver", silver);
		
		Channel<String> guiReceive = new Channel<String>(Util.GUI_SEND);
		
		while (true) {
			String mapa = guiReceive.receive();
			
//			Tablero.limpiar();
			
			Map<String,Set<String>> map = ConcurBattles.parsePaths(mapa);
			Map<String,Ciudad> locaciones = new HashMap<String, Ciudad>();
			
			for (String id : map.keySet()) {
				if (id.equals("1")) {
					locaciones.put(id, new Castillo(1, gold));
				} else if (id.equals(Integer.toString(map.size()))) {
					locaciones.put(id, new Castillo(map.size(), silver));
				} else {
					locaciones.put(id, new Ciudad(Integer.parseInt(id), null));
				}
			}
			
			for (String id : map.keySet()) {
				locaciones.get(id).setDestinos(new ArrayList<Ciudad>());
				for (String idDestino : map.get(id)) {
					locaciones.get(id).getDestinos() .add(locaciones.get(idDestino));
				}
			}
			
			gold.setCastillo(locaciones.get("1"));
			silver.setCastillo(locaciones.get(new Integer(locaciones.size()).toString()));
			
			List<Unidad> unidades = new ArrayList<Unidad>();
			unidades.add(new Unidad(gold));
			unidades.add(new Unidad(silver));
			
			Tablero tablero = Tablero.newInstance(unidades,	locaciones, bandos);
			tablero.comenzarJuego();
		}
	}
	
}
